/*
 * Copyright (c) 2010-2020 Belledonne Communications SARL.
 *
 * This file is part of linphone-android
 * (see https://www.linphone.org).
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package com.newlink.building.activities.main.settings.fragments

import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.view.LayoutInflater
import android.view.View
import android.view.inputmethod.EditorInfo
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.lifecycle.ViewModelProvider
import com.newlink.building.BR
import com.newlink.building.NL_App.Companion.coreContext
import com.newlink.building.R
import com.newlink.building.activities.main.settings.Module_Phone_SettingListenerStub
import com.newlink.building.activities.main.settings.viewmodels.Module_Phone_CallSettingsViewModel
import com.newlink.building.activities.navigateToAudioCodecSetting
import com.newlink.building.activities.navigateToVideoCodecSetting
import com.newlink.building.databinding.SettingsCallFragmentBinding
import com.newlink.building.utils.Module_Phone_Event
import com.newlink.building.utils.Module_Phone_ToastUtils
import com.newlink.building.widget.Module_Phone_CustomAlertDialog
import com.newlink.building.widget.Module_Phone_CustomInputDialog
import org.linphone.core.tools.Log
import org.linphone.mediastream.Version

object CallInputType {
    const val TYPE_PAYLOAD_VIDEO = 0x01
    const val TYPE_PAYLOAD_AUDIO = 0x02
}

class CallSettingsFragment : Module_Phone_GenericSettingFragment<SettingsCallFragmentBinding>() {
    private lateinit var viewModel: Module_Phone_CallSettingsViewModel

    override fun getLayoutId(): Int = R.layout.settings_call_fragment

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        var startTime = System.currentTimeMillis()
        super.onViewCreated(view, savedInstanceState)

        binding.lifecycleOwner = viewLifecycleOwner
        binding.sharedMainViewModel = sharedViewModel

        viewModel = ViewModelProvider(this)[Module_Phone_CallSettingsViewModel::class.java]
        binding.viewModel = viewModel

        binding.setBackClickListener {
            goBack()
        }

        binding.setSaveClickListener {
            Log.e("jake =>  Call settings save clicked")
            if (viewModel.checkPreferenceChanged()) {
                viewModel.savePreferenceChanged()
                Module_Phone_ToastUtils.showTextToast(context!!, "保存成功")
            } else {
                Module_Phone_ToastUtils.showTextToast(context!!, "没有修改的内容")
            }
        }

        binding.setVideoPayloadTypeClickListener {
            showCustomInputDialog(
                resources.getString(R.string.settings_call_payload_type_video),
                CallInputType.TYPE_PAYLOAD_VIDEO,
                "${viewModel.videoPayloadNum.value}",
                inputHide = resources.getString(R.string.settings_call_payload_type_range),

                )
        }

        binding.setAudioPayloadTypeClickListener {
            showCustomInputDialog(
                resources.getString(R.string.settings_call_payload_type_audio),
                CallInputType.TYPE_PAYLOAD_AUDIO,
                "${viewModel.audioPayloadNum.value}",
                inputHide = resources.getString(R.string.settings_call_payload_type_range),

                )
        }

        viewModel.goToAndroidNotificationSettingsEvent.observe(
            viewLifecycleOwner
        ) {
            it.consume {
                if (Build.VERSION.SDK_INT >= Version.API26_O_80) {
                    val i = Intent()
                    i.action = Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS
                    i.putExtra(Settings.EXTRA_APP_PACKAGE, requireContext().packageName)
                    i.putExtra(
                        Settings.EXTRA_CHANNEL_ID,
                        getString(R.string.notification_channel_service_id)
                    )
                    i.addCategory(Intent.CATEGORY_DEFAULT)
                    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                    i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
                    i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
                    startActivity(i)
                }
            }
        }

        viewModel.videoCodecListener = object : Module_Phone_SettingListenerStub() {
            override fun onClicked() {
                navigateToVideoCodecSetting(binding.slidingPane)
            }
        }

        viewModel.audioCodecListener = object : Module_Phone_SettingListenerStub() {
            override fun onClicked() {
                navigateToAudioCodecSetting(binding.slidingPane)
            }
        }

        viewModel.askAudioRecordPermissionForEchoTesterEvent.observe(
            viewLifecycleOwner
        ) {
            it.consume {
                Log.i("jake==> [CallSettingsFragment] Asking for RECORD_AUDIO permission for echo tester")
                requestPermissions(arrayOf(android.Manifest.permission.RECORD_AUDIO), 2)
            }
        }
        initVideoCodecsList()
    }

    private fun initVideoCodecsList() {
        val list = arrayListOf<ViewDataBinding>()
        for (payload in coreContext.core.videoPayloadTypes) {
            if (payload.mimeType == "H264") {
                val binding = DataBindingUtil.inflate<ViewDataBinding>(
                    LayoutInflater.from(requireContext()),
                    R.layout.settings_widget_switch_and_text,
                    null,
                    false
                )
                binding.setVariable(BR.switch_title, payload.mimeType)
                binding.setVariable(BR.switch_subtitle, "")
                binding.setVariable(BR.text_title, "recv-fmtp")
                binding.setVariable(BR.text_subtitle, "")
                binding.setVariable(BR.defaultValue, payload.recvFmtp)
                binding.setVariable(BR.checked, payload.enabled())
                binding.setVariable(
                    BR.listener,
                    object : Module_Phone_SettingListenerStub() {
                        override fun onBoolValueChanged(newValue: Boolean) {
                            payload.enable(newValue)
                        }

                        override fun onTextValueChanged(newValue: String) {
                            payload.recvFmtp = newValue
                            Log.i("jake==> [CallSettingsFragment] onTextValueChanged recvFmtp:${payload.recvFmtp}")
                        }
                    }
                )
                binding.lifecycleOwner = viewLifecycleOwner
                list.add(binding)
            }
            viewModel.videoCodecs.value = list
        }
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        val granted =
            grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED
        if (granted) {
            Log.i("jake==> [CallSettingsFragment] RECORD_AUDIO permission granted")
            if (requestCode == 1) {
                viewModel.startEchoCancellerCalibration()
            } else if (requestCode == 2) {
                viewModel.startEchoTester()
            }
        } else {
            Log.w("jake==> [CallSettingsFragment] RECORD_AUDIO permission denied")
        }
    }

    override fun goBack() {

        Log.e("jake->", "CallSettingfragment onGoback")
        if (viewModel.checkPreferenceChanged()) {
            showPreferenciesChangedDialog(context!!)
            return
        }
        exitPage()
    }

    private fun showPreferenciesChangedDialog(context: Context) {

        val dialog = Module_Phone_CustomAlertDialog(context).apply {
            setTitle(R.string.settings_save_warning_title)
            setContentText(resources.getString(R.string.settings_save_warning_content))
            setPositiveButton(resources.getString(R.string.save_dialog_custom)) {
                viewModel.savePreferenceChanged()
                exitPage()
                this.dismiss()
            }
            setNegativeButton(resources.getString(R.string.cancel_dialog_custom)) {
                exitPage()
                this.dismiss()
            }
        }
        dialog.show()
    }

    private fun exitPage() {
        sharedViewModel.hideNavigationBar.value = false
        sharedViewModel.jumpToSettingsPage.value = Module_Phone_Event(true)
    }

    private fun showCustomInputDialog(
        tittle: String,
        type: Int,
        inputText: String?,
        inputType: Int = EditorInfo.TYPE_CLASS_NUMBER,
        inputHide: String = "",
        maxLength: Int = 0
    ) {

        context?.let {
            val customInputDialog = Module_Phone_CustomInputDialog(it)
            customInputDialog.setTitle(tittle).setType(type).setInputText(inputText)
                .setInputHint(inputHide)
                .setMaxLength(maxLength)
                .setInputType(inputType)
                .setNegativeButton(
                    listener = object : Module_Phone_CustomInputDialog.OnClickListener {
                        override fun onClick(type: Int, inputText: String) {
                            customInputDialog.dismiss()
                        }
                    }
                ).setPositiveButton(
                    listener = object : Module_Phone_CustomInputDialog.OnClickListener {
                        override fun onClick(type: Int, inputText: String) {
                            val inputValue = inputText.toInt()
                            if (inputValue in 96..127) {
                                when (type) {
                                    CallInputType.TYPE_PAYLOAD_AUDIO -> viewModel.audioPayloadNum.value =
                                        inputText.toInt()

                                    CallInputType.TYPE_PAYLOAD_VIDEO -> viewModel.videoPayloadNum.value =
                                        inputText.toInt()

                                    else -> {}
                                }
                            } else {
                                Module_Phone_ToastUtils.showTextToast(
                                    context!!,
                                    R.string.settings_call_payload_type_warning
                                )
                            }

                            customInputDialog.dismiss()
                        }
                    }
                )
            customInputDialog.show()
        }
    }
}
